package com.ys.chatserver.rtc;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.eva.epc.common.util.CommonUtils;
import com.eva.framework.utils.LoggerFactory;
import com.google.gson.Gson;
import com.ys.chatserver.common.dto.cnst.RtcRedisKeyConstants;
import com.ys.chatserver.common.dto.cnst.UserProtocalsType;
import com.ys.chatserver.http.logic.LogicProcessor2;
import com.ys.chatserver.im.dto.CMDSosRequest;
import com.ys.chatserver.im.dto.NotifyEnum;
import com.ys.chatserver.im.dto.PushResDTO;
import com.ys.chatserver.im.impl.ChatLogicManager;
import com.ys.chatserver.im.util.MessageHelper;
import com.ys.chatserver.redis.RedisUtil;
import org.slf4j.Logger;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

public class RtcStreamNotifyServlet extends HttpServlet {

    Logger logger = LoggerFactory.getLog();

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String str = req.getReader().readLine();
        RtcStreamNotify obj = JSONObject.parseObject(str, RtcStreamNotify.class);
        try {
            dispatch(obj, resp);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    protected void dispatch(RtcStreamNotify prRequest, HttpServletResponse resp) throws Exception {
        logger.info("-------------------------------------------------------------------stream---------------------------------------------------------");
        String stream = prRequest.getStream();
        boolean regist = prRequest.isRegist();
        String app = prRequest.getApp();
        if (!regist) {
            if (!CommonUtils.isStringEmpty(stream)) {
                String[] strings = stream.split("-");
                if (app.equals(ConstRtcApp.APP_LIVE)) {//视频推流结束
                    if (stream.startsWith(ConstRtcApp.USER)) {//用户
                        if (strings.length == 4) { //头+群ID+用户ID+时间戳
                            String groupId = strings[1];
                            String userId = strings[2];
                            CMDSosRequest cmdSosRequest = new CMDSosRequest();
                            cmdSosRequest.setT(groupId);
                            cmdSosRequest.setF(userId);
                            ChatLogicManager.processMT59_VIDEO_SUCCESS_NOTIFICATION$REQ_B$TO$Message2(cmdSosRequest);
                            Vector<Vector<?>> vectors = LogicProcessor2.db.queryData("select user_type from g_users where user_uid = '" + userId + "'");
                            if (!vectors.isEmpty() && vectors.get(0).get(0).toString().equals("1")) {
                                closeListenChannel(groupId.split("_")[1], userId);
                            }
                        }
                    } else if (stream.startsWith(ConstRtcApp.DEV)) {//头+设备ID+时间戳
                        String devId = strings[1];
                        CMDSosRequest cmdSosRequest = new CMDSosRequest();
                        cmdSosRequest.setF(devId);
                        ChatLogicManager.processMT66_VIDEO_SUCCESS_NOTIFICATION$REQ_B$TO$Message(cmdSosRequest);
                    }else if (strings.length == 2 && strings[0].equals("device")) {
                        Vector<Vector<?>> vectors = LogicProcessor2.db.queryData("select base_id,node_pid from chat_group_node where node_type = 'USER' and user_uid = '" + strings[1] + "' and g_status = 1");
                        if (!vectors.isEmpty()) {
                            String groupId = vectors.get(0).get(0).toString() + "_" + vectors.get(0).get(1).toString();
                            // push third dev offline
                            pushThirdDevOfflineStatus(strings[1]);
                            thirdDeviceEndPush(groupId, strings[1], stream);
                        }
                    }
                } else if (app.equals(ConstRtcApp.APP_PTT)) {//音频推流结束
                    if (stream.contains("SOS")) {
                        //全频对讲SOS  头+SOS+群ID+频道ID+用户ID+时间戳
                        String groupId = strings[2];
                        String[] split = groupId.split("_");
                        String userId = strings[4];
                        String key = RtcRedisKeyConstants.GET_SOS_GROUP_KEY(split[0], split[1]);
                        if (RedisUtil.exists(key)) {
                            RedisUtil.del(key);
                        }
                        CMDSosRequest cmdSosRequest = new CMDSosRequest();
                        cmdSosRequest.setT(groupId);
                        cmdSosRequest.setF(userId);
                        String urlData = ConstRtcApp.USER + "-SOS-" + groupId + "-" + split[1] + "-" + userId + "-" + strings[5];
                        ChatLogicManager.processMT63_OF_SOS_ALL_NOTIFICATION_SUCCESS_REMOVE_KEY(cmdSosRequest, urlData);
                    } else if (stream.contains("ONEKEY")) {
                        //一键到底  头+SOS+群ID+级别+用户ID+时间戳
                        String groupId = strings[2];
                        String[] arr = groupId.split("_");
                        String userId = strings[4];
                        if (RedisUtil.exists(RtcRedisKeyConstants.GET_ONE_GROUP_KEY(arr[0], strings[3], userId, arr[1]))) {
                            RedisUtil.del(RtcRedisKeyConstants.GET_ONE_GROUP_KEY(arr[0], strings[3], userId, arr[1]));
                        }
                        String urlData = ConstRtcApp.USER + "-ONEKEY-" + groupId + "-" + strings[3] + "-" + userId + "-" + strings[5];
                        CMDSosRequest cmdSosRequest = new CMDSosRequest();
                        cmdSosRequest.setT(groupId);
                        cmdSosRequest.setF(userId);
                        ChatLogicManager.processMT72_OF_ONEKEY_ALL_NOTIFICATION_SUCCESS_REMOVE_KEY(cmdSosRequest, strings[3], urlData);
                    } else if (stream.contains("PHONE")) {
                        String[] split = stream.split("-");
                        String fuserId = split[1];
                        String toUserId = split[2];
                        PushResDTO dto = new PushResDTO();
                        dto.setType(NotifyEnum.FOUR.getType());
                        dto.setPushId(fuserId);
                        dto.setUrlData("PHONE-" + fuserId + "-" + toUserId + "-" + split[3]);
                        String json = new Gson().toJson(dto);
                        MessageHelper.processMT74RTC_CALL_PHONE(fuserId, json, null);
                    } else {
                        //频道对讲 头+群ID+频道ID+用户ID+时间戳
                        String groupId = strings[1];
                        String[] split = groupId.split("_");
                        String userId = strings[3];
                        String key = RtcRedisKeyConstants.GET_PTT_GROUP_KEY(split[0], split[1]);
                        if (RedisUtil.exists(key)) {
                            RedisUtil.del(key);
                        }
                        final String urlData = ConstRtcApp.USER + "-" + split[0] + "_" + split[1] + "-" + split[1] + "-" + userId + "-" + strings[4];
                        CMDSosRequest cmdSosRequest = new CMDSosRequest();
                        cmdSosRequest.setT(groupId);
                        cmdSosRequest.setF(userId);
                        cmdSosRequest.setM(split[1]);
                        ChatLogicManager.processMT56_OF_SOS_NOTIFICATION_SUCCESS_REMOVE_KEY(cmdSosRequest, urlData, false);

                    }
                }
            }
        } else {
            if (!CommonUtils.isStringEmpty(stream)) {
                String[] strings = stream.split("-");
                if (app.equals(ConstRtcApp.APP_LIVE)) {
                    if (stream.startsWith(ConstRtcApp.USER)) {
                        if (strings.length == 4) { //头+群ID+用户ID+时间戳
                            RedisUtil.set(RtcRedisKeyConstants.DEVICE_LIVE_KEY(strings[1], strings[2]), strings[3]);
                            String userId = strings[2];
                            Vector<Vector<?>> vectors = LogicProcessor2.db.queryData("select user_type from g_users where user_uid = '" + userId + "'");
                            if (!vectors.isEmpty() && vectors.get(0).get(0).toString().equals("1")) {
                                processACTION_DEVICE_START_PUSH_STREAM(strings[1], userId, prRequest.getStream());
                            }
                            if (!vectors.isEmpty() && vectors.get(0).get(0).toString().equals("0")) {
                                processMT58_VIDEO_NOTIFICATION$REQ_B$TO$Message_2(strings[1], strings[2], strings[3]);
                            }
                        }
                    } else if (stream.startsWith(ConstRtcApp.DEV)) {
                        if (strings.length == 3) { //头+设备ID+时间戳
                            Map<String, String> videoMap = UserProtocalsType.DEV_VIDEO_MAP;
                            String key = strings[1];
                            videoMap.put(key, strings[2]);
                        }
                    }else if (strings.length == 2 && strings[0].equals("device")) {
                        // 第三方设备推流，通知频道其他人
                        thirdDeviceStartPush(strings[1], prRequest.getStream());
                    }
                } else if (app.equals(ConstRtcApp.APP_PTT)) {
                    if (stream.contains("SOS")) {
                        //全频对讲SOS  头+SOS+群ID+频道ID+用户ID+时间戳
                        String a = "sos-" + strings[2] + "-" + strings[4] + "-" + strings[5];
                        logger.debug("--------------a:{}----------------", a);
                        if (RedisUtil.exists(a)) {
                            RedisUtil.del(a);
                        }
                        String[] split = strings[2].split("_");
                        String key = RtcRedisKeyConstants.GET_SOS_GROUP_KEY(split[0], split[1]);
                        String value = strings[4] + "-" + strings[5];
                        RedisUtil.set(key, value, 65L);
                    } else if (stream.contains("ONEKEY")) {
                        //一键到底  头+ONEKEY+群ID+级别+用户ID+时间戳
                        String[] split = strings[2].split("_");
                        RedisUtil.set(RtcRedisKeyConstants.GET_ONE_GROUP_KEY(split[0], strings[3], strings[4], split[1]), "", 65);
                    } else if (stream.contains("PHONE")) {
                        logger.info("phone->{}", stream);
                    } else {
                        //频道对讲 头+群ID+频道ID+用户ID+时间戳
                        String s = "ptt-" + strings[1] + "-" + strings[3] + "-" + strings[4];
                        System.out.println("s:" + s);
                        RedisUtil.del(s);
                        String[] split = strings[1].split("_");
                        String key = RtcRedisKeyConstants.GET_PTT_GROUP_KEY(split[0], split[1]);
                        String value = strings[3] + "-" + strings[4];
                        RedisUtil.set(key, value, 65);
                    }
                }
            }
        }
        LoggerFactory.getLog().info("[RtcStreamNotify]   -> " + prRequest.toString());
        String str = JSONObject.toJSON(RtcCommonAck.authSuccess()).toString();
        resp.getWriter().write(str);
        resp.setStatus(200);
    }

    public static void processMT58_VIDEO_NOTIFICATION$REQ_B$TO$Message(String groupId,String userId,String time) throws Exception {
        String[] arr = groupId.split("_");
        String sql = "select user_uid from chat_group_node where base_id ='" + arr[0] + "' and node_pid = '" + arr[1] + "' and g_status = 1 and node_type = 'USER'";
        Vector<Vector<?>> vectors = LogicProcessor2.db.queryData(sql);
        if (!Objects.isNull(vectors) && vectors.size() > 1) {
            for (Vector<?> vector : vectors) {
                String str = vector.get(0).toString();
                if (userId.equals(str)) {
                    continue;
                }

                PushResDTO dto = new PushResDTO();
                String urlData = ConstRtcApp.USER + "-" + groupId + "-" + userId + "-" + time;
                dto.setUrlData(urlData);
                dto.setAppType(ConstRtcApp.APP_LIVE);
                dto.setGroupId(groupId);
                dto.setPushId(userId);
                dto.setType(NotifyEnum.FIVE.getType());
                String json = new Gson().toJson(dto);
                MessageHelper.processMT58_VIDEO_NOTIFICATION$REQ_B$TO$Message(str, json, null);
            }
        }
    }

    private static void thirdDeviceStartPush(String userUid, String dataUrl) throws Exception {
        Vector<Vector<?>> userVector = LogicProcessor2.db.queryData("select user_type from g_users where del_flag = 0 and user_uid = '" + userUid + "' ");
        if (!userVector.isEmpty()) {
            String userType = userVector.get(0).get(0).toString();
            if (Objects.equals(userType, "2")) {
                LogicProcessor2.db.update(Collections.singletonList("update g_users set is_online = true where del_flag is false and user_type = 2 and user_uid = '" + userUid + "'"), true);


                Vector<Vector<?>> res = LogicProcessor2.db.queryData("select c.base_id,c.node_pid from chat_group_node c left join g_users g on  g.user_uid = c.user_uid" +
                        " where c.node_type = 'USER' and c.g_status = 1 and g.del_flag = 0 and g.user_type = 2 and g.user_uid = '" + userUid + "'");
                if (!res.isEmpty()) {
                    String groupId = res.get(0).get(0).toString();
                    String nId = res.get(0).get(1).toString();
                    RedisUtil.set(RtcRedisKeyConstants.DEVICE_LIVE_KEY(groupId + "_" + nId, userUid), dataUrl);
                    String sql = "select user_uid from chat_group_node where base_id ='" + groupId + "' and node_pid = '" + nId + "' and g_status = 1 and node_type = 'USER'";
                    Vector<Vector<?>> response = LogicProcessor2.db.queryData(sql);
                    if (!Objects.isNull(response) && response.size() > 1) {
                        for (Vector<?> vector : response) {
                            String str = vector.get(0).toString();
                            if (userUid.equals(str)) {
                                continue;
                            }
                            // push online status
                            MessageHelper.sendOnlineMessage(str, JSON.toJSONString(userUid), null);

                            // push open stream status
                            PushResDTO resDTO = new PushResDTO();
                            resDTO.setUrlData(dataUrl);
                            resDTO.setAppType(ConstRtcApp.APP_LIVE);
                            resDTO.setGroupId(groupId + "_" + nId);
                            resDTO.setPushId(userUid);
                            resDTO.setType(NotifyEnum.FIVE.getType());
                            MessageHelper.processMT58_VIDEO_NOTIFICATION$REQ_B$TO$Message(str, new Gson().toJson(resDTO), null);
                        }
                    }
                }
            }
        }
    }

    private static void pushThirdDevOfflineStatus(String userUid) throws Exception {
        Vector<Vector<?>> userVector = LogicProcessor2.db.queryData("select user_type from g_users where del_flag = 0 and user_uid = '" + userUid + "' ");
        if (!userVector.isEmpty() && Objects.equals("2", userVector.get(0).get(0).toString())) {
            LogicProcessor2.db.update(Collections.singletonList("update g_users set is_online = false where del_flag is false and user_type = 2 and user_uid = '" + userUid + "'"), true);

            Vector<Vector<?>> res = LogicProcessor2.db.queryData("select c.base_id,c.node_pid from chat_group_node c left join g_users g on  g.user_uid = c.user_uid" +
                    " where c.node_type = 'USER' and c.g_status = 1 and g.del_flag = 0 and g.user_type = 2 and g.user_uid = '" + userUid + "'");
            if (!res.isEmpty()) {
                String groupId = res.get(0).get(0).toString();
                String nId = res.get(0).get(1).toString();
                String sql = "select user_uid from chat_group_node where base_id ='" + groupId + "' and node_pid = '" + nId + "' and g_status = 1 and node_type = 'USER'";
                Vector<Vector<?>> response = LogicProcessor2.db.queryData(sql);
                if (!Objects.isNull(response) && response.size() > 1) {
                    for (Vector<?> vector : response) {
                        String str = vector.get(0).toString();
                        if (userUid.equals(str)) {
                            continue;
                        }
                        // push offline status
                        MessageHelper.sendOfflineMessage(str, JSON.toJSONString(userUid), null);
                    }
                }
            }
        }
    }

    public static void processACTION_DEVICE_START_PUSH_STREAM(String groupId, String userId, String urlData) throws Exception {
        String[] arr = groupId.split("_");
        long time = System.currentTimeMillis();
        String sql = "select c.user_uid from chat_group_node c left join g_users s on s.user_uid = c.user_uid where s.user_type = 0 and s.del_flag is false and c.base_id ='" + arr[0] + "' and c.node_pid = '" + arr[1] + "' and c.g_status = 1 and c.node_type = 'USER'";
        Vector<Vector<?>> vectors = LogicProcessor2.db.queryData(sql);
        if (!Objects.isNull(vectors) && vectors.size() > 1) {
            for (Vector<?> vector : vectors) {
                String str = vector.get(0).toString();
                if (userId.equals(str)) {
                    continue;
                }
                PushResDTO dto = new PushResDTO();
                dto.setUrlData(urlData);
                dto.setAppType(ConstRtcApp.APP_LIVE);
                dto.setGroupId(groupId);
                dto.setPushId(userId);
                dto.setType(NotifyEnum.FIVE.getType());
                String json = new Gson().toJson(dto);
                MessageHelper.processMT58_VIDEO_NOTIFICATION$REQ_B$TO$Message(str, json, null);
            }
        }
    }

    public static void closeListenChannel(String channelId, String fromUserId) throws Exception {
        String sql = "select base_id from chat_group_node where node_id = '" + channelId + "' and g_status = 1 and node_type = 'MAIN_CHANNEL'";
        Vector<Vector<?>> vectors = LogicProcessor2.db.queryData(sql);
        if (!vectors.isEmpty()) {
            String groupId = vectors.get(0).get(0).toString();
            Set<String> keys = RedisUtil.keys(RtcRedisKeyConstants.CHANNEL_LINSTEN_USER_KEYS);
            if (keys != null && !keys.isEmpty()) {
                long count = keys.stream().filter(a -> a.contains(fromUserId) && a.contains(channelId) && a.contains(groupId)).count();
                if (count != 0) {
                    RedisUtil.del(RtcRedisKeyConstants.CHANNEL_LISTEN_USER_KEY(fromUserId, channelId, groupId));
                    String key = RtcRedisKeyConstants.GET_PTT_GROUP_KEY(groupId, channelId);
                    if (RedisUtil.exists(key)) {
                        RedisUtil.del(key);
                    }
                }
            }
        }
    }

    public static void processMT58_VIDEO_NOTIFICATION$REQ_B$TO$Message_2(String groupId, String userId, String time) throws Exception {
        String[] arr = groupId.split("_");
        String sql = "select c.user_uid from chat_group_node c left join g_users s on s.user_uid = c.user_uid where s.user_type = 0 and s.del_flag is false and c.base_id ='" + arr[0] + "' and c.node_pid = '" + arr[1] + "' and c.g_status = 1 and c.node_type = 'USER'";
        Vector<Vector<?>> vectors = LogicProcessor2.db.queryData(sql);
        if (!Objects.isNull(vectors) && vectors.size() > 1) {
            for (Vector<?> vector : vectors) {
                String str = vector.get(0).toString();
                if (userId.equals(str)) {
                    continue;
                }

                PushResDTO dto = new PushResDTO();
                String urlData = ConstRtcApp.USER + "-" + groupId + "-" + userId + "-" + time;
                dto.setUrlData(urlData);
                dto.setAppType(ConstRtcApp.APP_LIVE);
                dto.setGroupId(groupId);
                dto.setPushId(userId);
                dto.setType(NotifyEnum.FIVE.getType());
                String json = new Gson().toJson(dto);
                MessageHelper.processMT58_VIDEO_NOTIFICATION$REQ_B$TO$Message(str, json, null);
            }
        }
    }

    public static void thirdDeviceEndPush(String groupId, String userId, String urlData) throws Exception {
        String[] arr = groupId.split("_");
        String sql = "select c.user_uid from chat_group_node c left join g_users s on s.user_uid = c.user_uid where s.user_type = 0 and s.del_flag is false and c.base_id ='" + arr[0] + "' and c.node_pid = '" + arr[1] + "' and c.g_status = 1 and c.node_type = 'USER'";
        Vector<Vector<?>> vectors = LogicProcessor2.db.queryData(sql);
        if (!Objects.isNull(vectors) && vectors.size() > 1) {
            for (Vector<?> vector : vectors) {
                String str = vector.get(0).toString();
                if (userId.equals(str)) {
                    continue;
                }

                PushResDTO dto = new PushResDTO();
                dto.setUrlData(urlData);
                dto.setGroupId(groupId);
                dto.setPushId(userId);
                dto.setType(NotifyEnum.SIX.getType());
                String json = new Gson().toJson(dto);
                MessageHelper.processMT59_VIDEO_SUCCESS_NOTIFICATION$REQ_B$TO$Message(str, json, null);
            }
        }

        if (RedisUtil.exists(RtcRedisKeyConstants.DEVICE_LIVE_KEY(groupId, userId))) {
            RedisUtil.del(RtcRedisKeyConstants.DEVICE_LIVE_KEY(groupId, userId));
        }
    }

}
